package org.cybzacg.convert.converters.date;

import lombok.extern.slf4j.Slf4j;
import org.cybzacg.convert.annotation.Converter;
import org.cybzacg.convert.context.ConversionContext;
import org.cybzacg.convert.enums.ConversionPriority;
import org.cybzacg.convert.enums.ConversionType;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

/**
 * Instant转换器
 * 专门处理Instant类型的转换
 *
 * @author cybzacg.blog
 * @version 4.0
 * @since 3.0
 */
@Slf4j
@Converter(name = "InstantConverter", priority = ConversionPriority.MEDIUM_HIGH, description = "Instant类型转换器，处理各种类型到java.time.Instant的转换", enabled = true, version = "4.0", author = "cybzacg.blog", supportedTypes = {
        Instant.class }, tags = { "instant", "time", "conversion" })
public class InstantConverter extends AbstractDateTimeConverter<Instant> {

    public InstantConverter() {
        super(Instant.class, ConversionPriority.MEDIUM_HIGH);
    }

    @Override
    protected ConversionType getConversionType() {
        return ConversionType.INSTANT;
    }

    @Override
    protected Instant parseFromString(String str, DateTimeFormatter formatter) throws DateTimeParseException {
        // 尝试解析为 ZonedDateTime 然后转换为 Instant
        try {
            ZonedDateTime zonedDateTime = ZonedDateTime.parse(str, formatter);
            return zonedDateTime.toInstant();
        } catch (DateTimeParseException e) {
            // 尝试解析为 LocalDateTime 然后转换为 Instant
            try {
                LocalDateTime localDateTime = LocalDateTime.parse(str, formatter);
                return localDateTime.atZone(DEFAULT_ZONE_ID).toInstant();
            } catch (DateTimeParseException ex) {
                // 最后尝试解析为 LocalDate 然后转换为 Instant
                LocalDate localDate = LocalDate.parse(str, formatter);
                return localDate.atStartOfDay(DEFAULT_ZONE_ID).toInstant();
            }
        }
    }

    @Override
    protected Instant convertFromInstant(Instant instant, ConversionContext context) {
        // Instant 转换为自身，直接返回
        return instant;
    }

    @Override
    protected String[] getSupportedPatterns() {
        // 合并所有日期时间格式
        String[] timezonePatterns = org.cybzacg.convert.constants.DateFormats.TIMEZONE_FORMAT_PATTERNS;
        String[] datetimePatterns = org.cybzacg.convert.constants.DateFormats.DATETIME_FORMAT_PATTERNS;
        String[] datePatterns = org.cybzacg.convert.constants.DateFormats.DATE_FORMAT_PATTERNS;

        String[] allPatterns = new String[timezonePatterns.length + datetimePatterns.length + datePatterns.length];
        int pos = 0;
        System.arraycopy(timezonePatterns, 0, allPatterns, pos, timezonePatterns.length);
        pos += timezonePatterns.length;
        System.arraycopy(datetimePatterns, 0, allPatterns, pos, datetimePatterns.length);
        pos += datetimePatterns.length;
        System.arraycopy(datePatterns, 0, allPatterns, pos, datePatterns.length);

        return allPatterns;
    }

    @Override
    protected Instant convertFromOtherDateTime(Object source, ConversionContext context) {
        // LocalDateTime转换
        if (source instanceof LocalDateTime localDateTime) {
            return localDateTime.atZone(DEFAULT_ZONE_ID).toInstant();
        }

        // ZonedDateTime转换
        if (source instanceof ZonedDateTime zonedDateTime) {
            return zonedDateTime.toInstant();
        }

        // LocalDate转换
        if (source instanceof LocalDate localDate) {
            return localDate.atStartOfDay(DEFAULT_ZONE_ID).toInstant();
        }

        // LocalTime转换（今天的该时间）
        if (source instanceof LocalTime localTime) {
            return LocalDate.now().atTime(localTime).atZone(DEFAULT_ZONE_ID).toInstant();
        }

        return null;
    }

    @Override
    protected Instant getDefaultValue() {
        return org.cybzacg.convert.constants.DateTimeDefaults.INSTANT_DEFAULT;
    }
}
